package it.unibo.imola.gui;

import it.unibo.imola.parser.ParseException;
import it.unibo.imola.parser.Parser;
import it.unibo.imola.parser.TokenMgrError;
import it.unibo.imola.parser.syntaxtree.Root;
import it.unibo.imola.parser.visitor.ExecutorVisitor;
import it.unibo.imola.parser.visitor.TreeVisitor;
import it.unibo.imola.parser.visitor.entity.ToolBox;
import it.unibo.imola.parser.visitor.entity.ToolBoxFactory;
import it.unibo.imola.toolbox.javacv.JavaCVToolBox;
import it.unibo.imola.utils.ExceptionUtils;

import java.io.StringReader;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.PlatformUI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExecuteCommandHandler extends AbstractHandler {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		
		EditorView editorView = (EditorView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(EditorView.ID);
		ConsoleView consoleView = (ConsoleView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(ConsoleView.ID);
		TreeView treeView = (TreeView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(TreeView.ID);		
		Tree tree = treeView.getTree();
		
		consoleView.getStyledText().setText("");
		String text = editorView.getStyledText().getText();

		if (text == null) {
			if (logger.isDebugEnabled())
				logger.debug("text == null");
			return null;
		}
		
		if(text.isEmpty()) {
			if (logger.isDebugEnabled())
				logger.debug("text.isEmpty()");
			tree.removeAll();
			return null;
		}

		StringReader reader = new StringReader(text);
		Parser parser =  new Parser(reader);
		Root start = null;
		
		try
		{			
			start = parser.Root();
			
			consoleView.getStyledText().append("\nAnalisi lessicale e sintattica OK!");	

			tree.removeAll();

			TreeVisitor v = new TreeVisitor();
			start.accept(v,tree);
			treeView.expandAll();
						
		}
		catch(ParseException ex){
			if(logger.isErrorEnabled())
				logger.error(ExceptionUtils.getMessageForDebugLogging(ex));

			tree.removeAll();
			consoleView.getStyledText().append("\nSyntax Error: " + ex.getMessage());
			start = null;			
		}
		catch(TokenMgrError err){
			if(logger.isErrorEnabled())
				logger.error(ExceptionUtils.getMessageForDebugLogging(err));

			tree.removeAll();
			consoleView.getStyledText().append("\n"+err.getMessage());
			start = null;			
		}
		catch(Throwable e){
			if(logger.isErrorEnabled())
				logger.error(ExceptionUtils.getMessageForDebugLogging(e));
			
			tree.removeAll();
			start = null;		
		}

		reader.close();
		
		if (start != null) {

			try {
				ExecutorVisitor v = new ExecutorVisitor(new JavaCVToolBox());
				start.accept(v, null);

				consoleView.getStyledText().append("\nAnalisi semantica e valutazione OK!");
				
			} catch (Throwable e) {
				if (logger.isErrorEnabled())
					logger.error(ExceptionUtils.getMessageForDebugLogging(e));

				tree.removeAll();
				consoleView.getStyledText().append("\nSemantic Error: " + e.getMessage());
			}
		}							

		return null;
	}
}
